{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial 5: Parameter & Provider\n",
    "Now let's introduce an important module of our library: Parameter.\n",
    "\n",
    "Parameter is like an abstract class, and all classes that inherit it and override __init__ and gen methods in a particular format will be automatically managed using the parameter provider. \n",
    "\n",
    "For example, the beaver triplet, which are generated in the offline phase and used in the online phase, should inherit from the Parameter class.\n",
    "So that parameter provider can load these pregenerated instances of the class which inherits from Parameter into the memory on demand and take them out when needed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## How to create and use a new type of Parameter\n",
    "We can follow the following steps:\n",
    "\n",
    "First, create a new class that inherits the Parameter class. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-10-16T08:41:45.512482Z",
     "start_time": "2024-10-16T08:41:45.507372Z"
    }
   },
   "outputs": [],
   "source": [
    "from NssMPC import RingTensor, ArithmeticSecretSharing\n",
    "\n",
    "from NssMPC.crypto.aux_parameter import Parameter\n",
    "\n",
    "\n",
    "class MyParameter(Parameter):\n",
    "    def __init__(self, a=None, b=None, c=None):\n",
    "        # What attributes does the parameter contain\n",
    "        self.attr_a = a\n",
    "        self.attr_b = b\n",
    "        self.attr_c = c\n",
    "    \n",
    "    @staticmethod\n",
    "    def gen(num, param0):\n",
    "        # By what process is this parameter produced\n",
    "        # An example\n",
    "        a = RingTensor.random((num,))\n",
    "        b = RingTensor.convert_to_ring(param0).repeat((num,))\n",
    "        c = a + b\n",
    "        a_0, a_1 = ArithmeticSecretSharing.share(a)\n",
    "        b_0, b_1 = ArithmeticSecretSharing.share(b)\n",
    "        c_0, c_1 = ArithmeticSecretSharing.share(c)\n",
    "        return MyParameter(a_0, b_0, c_0), MyParameter(a_1, b_1, c_1)  # A pair of instances should be returned "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then we can generate the required number of class instances.\n",
    "\n",
    "You can also use the second parameter to specify the name of the saved file, but if you change the default Settings, you need to do so later when initializing the provider.Otherwise, this parameter defaults."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-10-16T08:41:45.630639Z",
     "start_time": "2024-10-16T08:41:45.513487Z"
    }
   },
   "outputs": [],
   "source": [
    "MyParameter.gen_and_save(100, 'testParam', 72)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When you have completed this step, you can call the following method to retrieve the required number of auxiliary parameters for calculation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from NssMPC.secure_model.utils.param_provider import ParamProvider\n",
    "from NssMPC.secure_model.mpc_party import SemiHonestCS\n",
    "\n",
    "p = SemiHonestCS('client')\n",
    "p.append_provider(ParamProvider(MyParameter, 'testParam'))\n",
    "p.online()\n",
    "\n",
    "my_param = p.get_param(MyParameter, 3)\n",
    "# do some calculate using my_param"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The server side also needs to be set up this way, you can consider encapsulating this process into a custom Party class."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
